// - 定义: 索引签名用于描述那些“通过索引得到”的类型
// - 格式: 如`[props: string]:any`
// - 应用场景: 解决参数问题

interface data {
  name: string;
  age: number;
  [propName: string]: any; // 可能接口存在很多属性，那么定义索引签名
}

let obj: data = { name: "张三", age: 18, sex: "男", address: "北京" };

interface IFullName {
  firstName: string;
  lastName: string;
  age?: number;
  singName?: string;
  [props: string]: any;
}

// 注意点: 如果使用接口来限定了变量或者形参, 那么在给变量或者形参赋值的时候,多一个或者少一个都不行
// 实际开发中往往会出现多或者少的情况，怎么解决？

// 少一个或者少多个属性
// 解决方案: 可选属性
let goddass1: IFullName = { firstName: "邱", lastName: "淑贞" };
let goddass2: IFullName = { firstName: "邱", lastName: "淑贞", age: 18 };

// 多一个或者多多个属性
// 方案一：使用变量
let info = {
  firstName: "邱",
  lastName: "淑贞",
  age: 18,
  singName: "赌王",
  dance: "芭蕾",
};
let goddass3: IFullName = info;

// 方案二: 使用类型断言
let goddass4: IFullName = {
  firstName: "邱",
  lastName: "淑贞",
  age: 18,
  singName: "赌王",
  dance: "芭蕾",
} as IFullName;

// 索引签名？
// 索引签名用于描述那些“通过索引得到”的类型
// 注意点: 对象中的键，会被转化为字符串
interface Ibeauty {
  [props: string]: string;
}

let name1: Ibeauty = { name1: "邱淑贞", name2: "李嘉欣", name3: "周慧敏" };

interface Iage {
  [props: string]: number;
}

let afe: Iage = { age1: 18, age2: 20 };

// 方案三: 索引签名
let goddass5: IFullName = {
  firstName: "邱",
  lastName: "淑贞",
  age: 18,
  singName: "赌王",
  dance: "芭蕾",
};
